4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
11 // You must not remove this notice, or any other, from this software.
16 namespace Microsoft
.JScript
{
18 using Microsoft
.JScript
.Vsa
;
20 using System
.Reflection
;
21 using System
.Reflection
.Emit
;
23 using System
.Globalization
;
26 using System
.Collections
.Specialized
;
28 internal class VsaStaticCode
: VsaItem
, IVsaCodeItem
{
29 internal Context codeContext
;
30 private Type compiledClass
;
31 private ScriptBlock block
;
33 internal VsaStaticCode(VsaEngine engine
, string itemName
, VsaItemFlag flag
)
34 : base(engine
, itemName
, VsaItemType
.Code
, flag
) {
35 this.compiledClass
= null;
36 this.codeContext
= new Context(new DocumentContext(this), "");
39 public void AddEventSource(string eventSourceName
, string eventSourceType
) {
40 // JScript does not support adding event sources (user must add an AppGlobal instead and manually hook up event handlers)
41 if (this.engine
== null)
42 throw new VsaException(VsaError
.EngineClosed
);
43 throw new System
.NotSupportedException();
46 public System
.CodeDom
.CodeObject CodeDOM
{
48 if (this.engine
== null)
49 throw new VsaException(VsaError
.EngineClosed
);
50 throw new VsaException(VsaError
.CodeDOMNotAvailable
);
54 public void AppendSourceText(string SourceCode
)
56 if (this.engine
== null)
57 throw new VsaException(VsaError
.EngineClosed
);
58 if (SourceCode
== null || SourceCode
.Length
== 0) return;
59 this.codeContext
.SetSourceContext(this.codeContext
.document
, this.codeContext
.source_string
+ SourceCode
);
60 this.compiledClass
= null;
62 this.engine
.IsDirty
= true;
65 internal override void CheckForErrors() {
66 if (this.compiledClass
== null) {
67 JSParser p
= new JSParser(this.codeContext
);
68 AST prog
= (ScriptBlock
)p
.Parse();
69 //prog.PartiallyEvaluate();
73 internal override void Close() {
75 this.codeContext
= null;
76 this.compiledClass
= null;
79 internal override Type
GetCompiledType() {
80 TypeBuilder tb
= this.compiledClass
as TypeBuilder
;
81 if (tb
!= null) this.compiledClass
= tb
.CreateType();
82 return this.compiledClass
;
85 public override String Name
{
88 if (this.codebase
== null){
89 // The codeContext document was named according to the engine's RootMoniker and the item name
90 string rootMoniker
= this.engine
.RootMoniker
;
91 this.codeContext
.document
.documentName
= rootMoniker
+ (rootMoniker
.EndsWith("/", StringComparison
.Ordinal
) ? "" : "/") + this.name
;
96 internal void Parse() {
97 if (this.block
== null && this.compiledClass
== null) {
98 GlobalScope glob
= (GlobalScope
)this.engine
.GetGlobalScope().GetObject();
99 //Provide for the possibility of forward references to declarations in code blocks yet to come.
100 glob
.evilScript
= !glob
.fast
|| this.engine
.GetStaticCodeBlockCount() > 1;
101 this.engine
.Globals
.ScopeStack
.Push(glob
);
103 JSParser p
= new JSParser(this.codeContext
);
104 this.block
= (ScriptBlock
)p
.Parse();
108 this.engine
.Globals
.ScopeStack
.Pop();
113 internal void ProcessAssemblyAttributeLists(){
114 if(this.block
== null) return;
115 this.block
.ProcessAssemblyAttributeLists();
118 internal void PartiallyEvaluate(){
119 if (this.block
!= null && this.compiledClass
== null){
120 GlobalScope glob
= (GlobalScope
)this.engine
.GetGlobalScope().GetObject();
121 this.engine
.Globals
.ScopeStack
.Push(glob
);
123 this.block
.PartiallyEvaluate();
124 if (this.engine
.HasErrors
&& !this.engine
.alwaysGenerateIL
)
125 throw new EndOfFile();
127 this.engine
.Globals
.ScopeStack
.Pop();
132 internal override void Remove() {
133 if (this.engine
== null)
134 throw new VsaException(VsaError
.EngineClosed
);
138 public void RemoveEventSource(string eventSourceName
)
140 if (this.engine
== null)
141 throw new VsaException(VsaError
.EngineClosed
);
142 throw new System
.NotSupportedException();
145 internal override void Reset() {
146 this.compiledClass
= null;
148 // We reset codeContext because the DocumentContext holds a reference to engine.compilerGlobals
149 // (which we must have set to null before calling Reset on the VsaItems).
150 this.codeContext
= new Context(new DocumentContext(this), this.codeContext
.source_string
);
153 internal override void Run() {
154 if (this.compiledClass
!= null) {
155 GlobalScope scriptBlockScope
= (GlobalScope
)Activator
.CreateInstance(this.GetCompiledType(), new Object
[]{this.engine.GetGlobalScope().GetObject()}
);
156 this.engine
.Globals
.ScopeStack
.Push(scriptBlockScope
);
158 MethodInfo main
= this.compiledClass
.GetMethod("Global Code");
160 main
.Invoke(scriptBlockScope
, null);
161 }catch(TargetInvocationException e
){
162 throw e
.InnerException
;
165 this.engine
.Globals
.ScopeStack
.Pop();
170 public override void SetOption(String name
, Object
value){
171 if (this.engine
== null)
172 throw new VsaException(VsaError
.EngineClosed
);
173 if (0 == String
.Compare(name
, "codebase", StringComparison
.OrdinalIgnoreCase
)){
174 this.codebase
= (string)value;
175 this.codeContext
.document
.documentName
= this.codebase
;
177 throw new VsaException(VsaError
.OptionNotSupported
);
179 this.engine
.IsDirty
= true;
182 public Object SourceContext
{
191 public String SourceText
{
193 if (this.engine
== null)
194 throw new VsaException(VsaError
.EngineClosed
);
195 return this.codeContext
.source_string
;
199 if (this.engine
== null)
200 throw new VsaException(VsaError
.EngineClosed
);
201 this.codeContext
.SetSourceContext(this.codeContext
.document
, (value == null ? "": value));
202 this.compiledClass
= null;
204 this.engine
.IsDirty
= true;
208 internal void TranslateToIL(){
209 if (this.block
!= null && this.compiledClass
== null){
210 GlobalScope glob
= (GlobalScope
)this.engine
.GetGlobalScope().GetObject();
211 this.engine
.Globals
.ScopeStack
.Push(glob
);
213 this.compiledClass
= this.block
.TranslateToILClass(this.engine
.CompilerGlobals
, false);
215 this.engine
.Globals
.ScopeStack
.Pop();